package quick.start.core.binding;

import java.lang.ref.WeakReference;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class WeakList<Entity> extends AbstractList<Entity> {

	private volatile ArrayList<WeakReference<Entity>> items;

    /** Creates new WeakList */
    public WeakList() {
        items = new ArrayList<WeakReference<Entity>>();
    }
    
    public WeakList(Collection<Entity> c) {
        items = new ArrayList<WeakReference<Entity>>();
        addAll(0, c);
    }

    public WeakList(int initCapcacity) {
        items = new ArrayList<WeakReference<Entity>>(initCapcacity);
    }

    
    public void add(int index, Entity element) {
    	synchronized(this){
    		items.add(index, new WeakReference<Entity>(element));
    	}
    }
    
    public Iterator<Entity> iterator() {
    	throw new UnsupportedOperationException();
//    	synchronized(this){
//    		return new WeakListIterator();
//    	}
    }
    
    public int size() {
    	synchronized(this){
	        removeReleased();
	        return items.size();
    	}
    }    
    
    public Entity get(int index) {
    	synchronized(this){
    		return ((WeakReference<Entity>) items.get(index)).get();
    	}
    }
    
    private void removeReleased() {
    	synchronized(this){
    		ArrayList<WeakReference<Entity>> removeList = new ArrayList<WeakReference<Entity>>();
	        for (Iterator<WeakReference<Entity>> it = items.iterator(); it.hasNext(); ) {
	            WeakReference<Entity> ref = (WeakReference<Entity>) it.next();
	            if (ref.get() == null) removeList.add(ref);
	        }
	        for(int i=0; i<removeList.size(); i++){
	        	items.remove(removeList.get(i));
	        }
    	}
    }
    
	public Object[] toArray() {
		synchronized(this){
	    	removeReleased();
	    	@SuppressWarnings("unchecked")
			WeakReference<Entity>[] itemArray = items.toArray(new WeakReference[0]);
	    	int len = itemArray.length;
	    	Object[] eArray = new Object[len];
	    	for(int i=0; i<len; i++){
	    		eArray[i] = itemArray[i].get();
	    	}
	    	return eArray;
		}
	}

	@Override
	public boolean remove(Object object) {
		synchronized(this){
			int len = items.size();
			for(int i=0; i<len; i++){
				if (items.get(i).get() == null){
					items.remove(i);
					return remove(object);
				}
				if (items.get(i).get().equals(object)){
					items.remove(i);
					return true;
				}
			}
			return false;
		}
	}

	@Override
	public boolean add(Entity object) {
		synchronized(this){
			return items.add(new WeakReference<Entity>(object));
		}
	}

}
